package com.tmt.im.wallet.controler;

import com.alibaba.fastjson2.JSONObject;
import com.tmt.im.wallet.controler.vo.ApplyWithdrawRequest;
import com.tmt.im.wallet.helper.PrincipalHelper;
import com.tmt.im.wallet.service.WithdrawHistoryService;
import com.tmt.springboot.common.restful.ExecuteResult;
import com.tmt.springboot.common.restful.IExecuteResult;
import com.tmt.springboot.common.restful.ResultWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.security.Principal;
import java.util.concurrent.CompletableFuture;

/**
 * 提现控制器
 *
 * @Description TODO
 * @Author wuyi
 * @Date 2024/10/19 16:18
 * @Version 1.0
 **/
@Slf4j
@Async("asyncTaskExecutor")
@Tag(name = "提现相关接口", description = "提现相关接口")
@RestController
@RequestMapping("${api-url-prefix}/withdraw")
public class WithdrawController {

    private final WithdrawHistoryService withdrawHistoryService;

    public WithdrawController(WithdrawHistoryService withdrawHistoryService) {
        this.withdrawHistoryService = withdrawHistoryService;
    }

    @Operation(summary = "提现申请接口",
            description = "提现申请接口",
            operationId = "applyWithdraw")
    @PostMapping(value = "/apply")
    public CompletableFuture<IExecuteResult<ResultWrapper<Boolean>>> applyWithdraw(@RequestBody @Validated ApplyWithdrawRequest request, Principal principal) {
        Long currentUserId = PrincipalHelper.getCurrentUserId(principal);
        IExecuteResult<Boolean> result = withdrawHistoryService.applyWithdraw(currentUserId, request, principal);
        return CompletableFuture.completedFuture(ResultWrapper.from(result));
    }

    @Operation(summary = "提现异步回调接口",
            description = "提现异步回调接口",
            operationId = "asyncConfirmWithdraw")
    @PostMapping(value = "/confirm/async")
    public CompletableFuture<IExecuteResult<ResultWrapper<Boolean>>> asyncConfirmWithdraw(HttpServletRequest request,
                                                                                          HttpServletResponse response) {
        log.error("----{}----", "asyncConfirmWithdraw");
        for (String key : request.getParameterMap().keySet()) {
            log.error("2----{}={}----", key, request.getParameterMap().get(key)[0]);
        }
        //接收提现回调的参数。
        Long withdrawHistoryId = withdrawHistoryService.asyncConfirmWithdraw(request);
        if (withdrawHistoryId != null) {
            withdrawHistoryService.updateWalletBalance(withdrawHistoryId);
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", 0);
        jsonObject.put("msg", "success");

        try (OutputStream out = response.getOutputStream()) {
            out.write(jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8));
        } catch (Exception ex) {
        }
        return CompletableFuture.completedFuture(null);
    }

    @Operation(summary = "提现结果查询接口",
            description = "提现结果查询接口",
            operationId = "queryWithdrawResult",
            parameters = {
                    @Parameter(name = "withdrawId", description = "要查询结果的提现记录ID")
            })
    @GetMapping(value = "/query")
    public CompletableFuture<IExecuteResult<ResultWrapper<Boolean>>> queryWithdrawResult(@RequestParam("withdrawId") Long withdrawId, Principal principal) {
        StringBuilder error = new StringBuilder();
        if (withdrawHistoryService.queryWithdrawResult(withdrawId, error)) {
            withdrawHistoryService.updateWalletBalance(withdrawId);
            return CompletableFuture.completedFuture(ResultWrapper.from(ExecuteResult.success(true)));
        }
        return CompletableFuture.completedFuture(ResultWrapper.from(ExecuteResult.failure(error.toString(), null)));
    }

}
